package com.order.config;

import io.lettuce.core.ReadFrom;
import org.redisson.Redisson;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;
import org.springframework.boot.autoconfigure.data.redis.RedisProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.RedisSentinelConfiguration;
import org.springframework.data.redis.connection.lettuce.LettuceClientConfiguration;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;

import javax.annotation.Resource;
import java.util.List;

@Configuration
public class RedisConfiguration {

    @Resource
    RedisProperties redisProperties;

    @Bean
    public RedisTemplate<String,Object> redisTemplate(){
        RedisTemplate<String,Object> redisTemplate = new RedisTemplate<>();
        redisTemplate.setConnectionFactory(lettuceConnectionFactory()); // 设置redis连接工厂并且实现读写分离
        // 配置Key与hashKey序列化器为StringRedisSerializer
        StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
        redisTemplate.setKeySerializer(stringRedisSerializer);
        redisTemplate.setHashKeySerializer(stringRedisSerializer);
        // 配置Value与hashValue序列化器为GenericJackson2JsonRedisSerializer
        GenericJackson2JsonRedisSerializer genericJackson2JsonRedisSerializer = new GenericJackson2JsonRedisSerializer();
        redisTemplate.setValueSerializer(genericJackson2JsonRedisSerializer);
        redisTemplate.setHashValueSerializer(genericJackson2JsonRedisSerializer);
        return redisTemplate;
    }

    @Bean
    public RedisConnectionFactory lettuceConnectionFactory(){
        return new LettuceConnectionFactory(getRedisSentinelConfiguration(), LettuceClientConfiguration.builder()
                .readFrom(ReadFrom.REPLICA_PREFERRED)
                .build());
    }

    @Bean
    public RedissonClient redissonClient(){
        Config config = new Config();
        RedisProperties.Sentinel sentinel = redisProperties.getSentinel();
        String master = sentinel.getMaster();   // 得到主节点的名称
        List<String> nodes = sentinel.getNodes();   // 得到哨兵集群的地址集合
        List<String> redisSentinelNodes = nodes.stream().map(node -> "redis://" + node).toList();
        // 配置redis哨兵集群
        config.useSentinelServers()
                .addSentinelAddress(redisSentinelNodes.toArray(String[]::new))
                .setMasterName(master);
        // 创建redis客户端
        return Redisson.create(config);
    }


    private RedisSentinelConfiguration getRedisSentinelConfiguration() {
        RedisProperties.Sentinel sentinel = redisProperties.getSentinel();
        RedisSentinelConfiguration config = new RedisSentinelConfiguration()
                .master(sentinel.getMaster());
        for (String node : sentinel.getNodes()) {
            String[] urls = node.split(":");
            config.sentinel(urls[0], Integer.parseInt(urls[1]));
        }
        return config;
    }


}
